﻿using Microsoft.SqlServer.Server;
using netDxf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using netDxf.Blocks;
using netDxf.Collections;
using netDxf.Entities;
using GTE = netDxf.GTE;
using netDxf.Header;
using netDxf.Objects;
using netDxf.Tables;
using netDxf.Units;
using Attribute = netDxf.Entities.Attribute;
using FontStyle = netDxf.Tables.FontStyle;
using Image = netDxf.Entities.Image;
using Point = netDxf.Entities.Point;
using Trace = netDxf.Entities.Trace;
using Vector2 = netDxf.Vector2;
using Vector3 = netDxf.Vector3;


namespace amtf_dxf2
{
    public class Startup
    {
        public async Task<object> Invoke(string message)
        {
            //return input;
            Console.WriteLine(message);
            //窗口.richTextBox1.Text += ("处理中：" + message + "\n");

            string[] ss = message.Split('|');
            string dxf全名 = ss[0];
            string 板厚mm = ss[1];
            string 计数 = ss[2];
            string 封边信息 = ss[3];
            处理dxf图层(dxf全名, 板厚mm, 计数, 封边信息);

            //switch (ss[0])
            //{
            //    case "调用amtf_dxf":
            //        处理dxf图层(dxf全名, 板厚mm, 计数, 封边信息);
            //        break;
            //    case "测试连接":
            //        break;
            //    default:
            //        break;
            //}
            return dxf全名;
        }
        static DxfDocument dxf;
        static string 板厚;
        static string 开料主信息;

        private static bool 匹配其中一个(string 拟匹配字符串, string pattern)
        {
            //string pattern = @"ABF_Label|deside";
            Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
            //string sentence = "Who writes these notes and uses our paper?";
            Match match = rgx.Match(拟匹配字符串);
            return match.Success;
        }
        private static void 炸开块(DxfDocument dxf)
        {
            //Program.窗口.richTextBox1.AppendText("dxf.Name"+ dxf.Name + "\n");

            if (dxf.Entities.Inserts.Count() > 0)
            {
                Insert 块 = dxf.Entities.Inserts.ElementAt(0);
                List<EntityObject> entities = 获取块内部元素(块);
                dxf.Entities.Remove(块);
                dxf.Entities.Add(entities);
            }
            if (dxf.Entities.Inserts.Count() > 0)
            {
                炸开块(dxf);
            }

        }
        private static void 炸开3dl(DxfDocument dxf)
        {
            if (dxf.Entities.Polylines3D.Count() > 0)
            {
                Polyline3D pd = dxf.Entities.Polylines3D.ElementAt(0);
                List<EntityObject> entities = pd.Explode();
                dxf.Entities.Remove(pd);
                dxf.Entities.Add(entities);
            }
            if (dxf.Entities.Polylines3D.Count() > 0)
            {
                炸开3dl(dxf);
            }

        }
        public static void 三dl转2dl测试()
        {
            dxf = Test(@"D:\桌面\测试.dxf");
            三dl转2dl(dxf);
            dxf.DrawingVariables.AcadVer = DxfVersion.AutoCad2007;
            dxf.Save(@"D:\桌面\AAA.dxf");
        }

        private static void 三dl转2dl(DxfDocument dxf)
        {
            //if (dxf.Entities.Polylines3D.Count() > 0)
            //foreach (var item in dxf.Entities.Polylines3D)
            //{
            //    Polyline2D p2d=item.ToPolyline2D(10);
            //}
            Debug.Print("p3d数量：" + dxf.Entities.Polylines3D.Count());
            if (dxf.Entities.Polylines3D.Count() > 0)
            {
                Polyline3D p3d = dxf.Entities.Polylines3D.ElementAt(0);
                Linetype kk = p3d.Linetype;
                Debug.Print("p3d类型名称=" + kk.Name);
                Polyline2D p2d = p3d.ToPolyline2D(10);
                //p2d.Thickness = -18;

                //2d多段线的法向可能是反的，给了厚度以后往z正方向跑，云熙会不识别，还得如下处理……
                Vector3 v3 = p2d.Normal;
                if (v3.Z == -1)
                {
                    v3.Z = 1;
                    p2d.Normal = v3;
                    //dxf.Entities.Add(line);

                    //Polyline2D reflection = (Polyline2D)p2d.Clone();
                    //reflection.Color = AciColor.Red;

                    // reflection matrix of a mirror plane given its normal and a point on the plane
                    Matrix4 reflectionMatrix = Matrix4.Reflection(new Vector3(1, 0, 0), new Vector3(0, 0, 0));

                    // for a mirror plane that passes through the origin, you can also use
                    //Matrix3 reflectionMatrix = Matrix3.Reflection(mirrorNormal);
                    p2d.TransformBy(reflectionMatrix);
                    //dxf.Entities.Add(reflection);

                }

                //List<EntityObject> 直线或圆弧=p2d.Explode();
                //foreach (var entity in 直线或圆弧)
                //{
                //    if (entity.Type == EntityType.Line)
                //    {
                //        Line line = (Line)entity;
                //        Vector3 v3 = line.Normal;
                //        if (v3.Z == -1)
                //        {
                //            v3.Z = 1;
                //            line.Normal = v3;
                //            //dxf.Entities.Add(line);
                //        }
                //    }
                //}
                dxf.Entities.Remove(p3d);
                dxf.Entities.Add(p2d);
                //dxf.Entities.Add(直线或圆弧);
            }
            if (dxf.Entities.Polylines3D.Count() > 0)
            {
                三dl转2dl(dxf);
            }

        }
        public static void 处理dxf图层(string 文件全名, string 板厚mm, string 计数, string 封边信息)
        {
            dxf = Test(文件全名);
            //Program.窗口.richTextBox1.AppendText("处理第 " + 计数 + " 个ing👇……\n");
            //Program.窗口.richTextBox1.AppendText(文件全名 + "\n");
            //Program.窗口.richTextBox1.AppendText("dxf.Name"+ dxf.Name + "\n");

            string 文件名 = Path.GetFileNameWithoutExtension(文件全名);
            string 文件路径 = Path.GetDirectoryName(文件全名);
            if (计数 == "1")
            {
                //Thread t = new Thread((ThreadStart)(() =>
                //{
                //    //需要处理的逻辑
                //    //Clipboard.SetText(文件路径);
                //}
                //));
                //t.SetApartmentState(ApartmentState.STA);
                //t.Start();
                //t.Join();
            }
            //string[] s1 = Regex.Split(文件名, "_板厚", RegexOptions.IgnoreCase);
            //开料主信息 = s1[0];
            板厚 = 板厚mm;
            开料主信息 = 文件名;


            炸开块(dxf);

            //炸开3dl(dxf);
            三dl转2dl(dxf);

            Console.WriteLine("图层总数: {0}", dxf.Layers.Count);
            //Program.窗口.richTextBox1.AppendText("图层总数:" + dxf.Layers.Count + "\n");

            //转移临时图层到最终图层
            foreach (var o in dxf.Layers)
            {
                string 图层名 = o.Name.ToUpper();
                //Console.WriteLine("图层名: {0}", 图层名);

                //if (匹配其中一个(图层名, "ABF_Label|dside"))
                ////if (匹配其中一个(图层名, "ABF_Label"))
                //{
                //    Console.WriteLine("schu图层名: {0}", 图层名);
                //    foreach (EntityObject entity in dxf.Layers.GetReferences(o))
                //    {
                //        //if (item.GetType() == typeof(Insert))
                //        //{
                //        dxf.Entities.Remove(entity);
                //        //}
                //    }
                //}
                string 关键词 = "-AMTF-";
                if (图层名.IndexOf(关键词) > -1)
                {
                    foreach (EntityObject entity in dxf.Layers.GetReferences(o))
                    {
                        string[] sArray = Regex.Split(图层名, 关键词, RegexOptions.IgnoreCase);
                        string 拟移动到的图层名 = sArray[0];
                        entity.Layer = dxf.Layers[拟移动到的图层名];
                        //entity.Lineweight = (Lineweight)500;
                        //Console.WriteLine("\t  entity.Type:{0}", entity.Type);
                        //Debug.WriteLine("\t  entity.Type:{0}", entity.Type);
                        dynamic kk = entity;

                        float 深度 = float.Parse(提取数字(图层名));
                        try
                        {
                            kk.Thickness = -深度;
                        }
                        catch (Exception)
                        {
                            //throw;
                        }

                        if (深度 == 0)
                        {
                            dxf.Entities.Remove(entity);
                            continue;
                        }
                        //通槽用蓝色，非通槽用bylayer
                        else if (深度 < float.Parse(板厚))
                        {
                            try
                            {
                                kk.Color = AciColor.ByLayer;

                                //这里可能是会把多边形通孔的表空间元素都设置了白色，然后云熙天工识别不了，也找不到原因
                                //kk.Color = new AciColor(255, 255, 255);
                            }
                            catch (Exception)
                            {
                                //throw;
                            }
                        }
                        else
                        {
                            try
                            {
                                kk.Color = AciColor.Blue;
                            }
                            catch (Exception)
                            {
                                //throw;
                            }
                        }

                        //圆的要特色处理
                        if (entity.Type == EntityType.Circle)
                        {
                            Debug.WriteLine("\t  entity.Type:{0}", entity.Type);
                            Circle circle = (Circle)entity;
                            Vector3 center = circle.Center;
                            center.Z = -深度;
                            Debug.WriteLine("\t  center.Z= -深度:{0}", -深度);
                            circle.Center = center;

                            Vector3 v3 = circle.Normal;
                            v3.Z = 1;
                            circle.Normal = v3;

                            if (深度 < float.Parse(板厚))
                            {
                                try
                                {
                                    kk.Color = new AciColor(255, 255, 255);
                                }
                                catch (Exception)
                                {
                                    //throw;
                                }
                            }
                            else//圆形通孔,如果想用钻孔的方式加工
                            {
                                if (circle.Radius <= 15)
                                {
                                    try
                                    {
                                        kk.Color = new AciColor(255, 255, 255);
                                    }
                                    catch (Exception)
                                    {
                                        //throw;
                                    }
                                }
                            }

                        }

                    }
                }
                if (匹配其中一个(图层名, "0|1"))
                {

                    //foreach (DxfObject entity in dxf.Layers.GetReferences(o))
                    //System.InvalidCastException:“Unable to cast object of type 'netDxf.Blocks.Block' to type 'netDxf.Entities.EntityObject'.”

                    foreach (DxfObject entity in dxf.Layers.GetReferences(o))
                    {
                        //Console.WriteLine("\t  entity.Type:{0}", entity.Type);
                        bool lx = entity.GetType() == typeof(Block);
                        if (lx)
                        {
                            Debug.WriteLine("\t  entity.Type=Block");
                        }
                        else
                        {
                            dynamic kk = entity;
                            EntityObject entity2 = (EntityObject)entity;
                            Debug.WriteLine("\t  entity.Type:{0}", entity2.Type);
                            if (entity2.Type == EntityType.Arc)
                            {
                                Arc arc = (Arc)entity;
                                Vector3 v3 = arc.Normal;
                                if (v3.Z == -1)//顺时针的圆弧,-x轴为0°
                                {
                                    double 开始角度 = arc.StartAngle;
                                    double 结束角度 = arc.EndAngle;
                                    //double radius = arc.Radius;
                                    //Vector3 ct = arc.Center;

                                    v3.Z = 1;
                                    arc.Normal = v3;
                                    arc.StartAngle = 180 - 结束角度;
                                    arc.EndAngle = 180 - 开始角度;
                                }


                                //Arc arc2 = new Arc(ct, radius,开始角度, 结束角度);
                                //arc2.Normal = new Vector3(0, 0, 1);
                                //dxf.Entities.Add(arc2);
                                //Arc arc3 = new Arc(ct, radius, 开始角度, 结束角度);
                                //arc3.Normal = new Vector3(0, 0, -1);
                                //dxf.Entities.Add(arc3);
                            }
                            try
                            {
                                kk.Color = AciColor.Red;
                                //kk.Color = AciColor.ByLayer;
                            }
                            catch (Exception e)
                            {
                                //netDxf.Blocks.Block' does not contain a definition for 'Color'”
                                Debug.Print(e.Message);
                                //Debug.Print(kk.Type);
                                //throw;
                            }
                        }
                    }
                }
            }

            TextStyle style = new TextStyle("True type font", "simkai.ttf");
            Layer layer = new Layer("TextToNest") { Color = AciColor.Cyan };
            //Vector3 v = new Vector3(1, 0, 0);
            Text text = new Text
            {
                //Attribute properties
                Layer = layer,
                Value = 开料主信息,
                Height = 25.0f,
                Style = style,
                Position = Vector3.Zero
            };

            dxf.Entities.Add(text);
            dxf.Blocks.Clear();
            dxf.Layers.Clear();
            dxf.TextStyles.Clear();

            string[] 封边信息s = Regex.Split(封边信息, "_", RegexOptions.IgnoreCase);
            string 启用封边 = 封边信息s[0];
            float 小于多少毫米 = float.Parse(封边信息s[1]);
            float 封边深度 = float.Parse(封边信息s[2]);
            if (启用封边 == "false")
            {
                //不用干啥
            }
            else
            {
                if (float.Parse(板厚) >= 小于多少毫米)
                {
                    foreach (var o in dxf.Layers)
                    {
                        string 图层名 = o.Name.ToUpper();
                        if ((匹配其中一个(图层名, "2|3|4|5")))
                        {
                            foreach (EntityObject entity in dxf.Layers.GetReferences(o))
                            {
                                dynamic kk = entity;
                                if (entity.Type == EntityType.Line)
                                {
                                    try
                                    {
                                        kk.Thickness = 封边深度;
                                    }
                                    catch (Exception)
                                    {
                                        //throw;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            dxf.DrawingVariables.AcadVer = DxfVersion.AutoCad2007;
            try
            {
                //dxf.Save(@"D:\桌面\AAA.dxf");
                dxf.Save(文件全名);
                //string kk = "处理完成: {0}", 文件全名;
                Console.WriteLine("处理完成: {0} \n", 文件全名);
                //string kk="\t  entity.Layer.Name:{0}", 文件全名;
                //Program.窗口.richTextBox1.Text += ("处理完成！\n");
                //Program.窗口.richTextBox1.AppendText("处理完成！\n");

            }
            catch (Exception e)
            {
                //throw;
                Console.WriteLine("人生处处有意外……↓");
                Console.WriteLine(e.Message);
                //Program.窗口.richTextBox1.Text += ("人生处处有意外……↓" + "\n");
                //Program.窗口.richTextBox1.Text += (e.Message + "\n");

            }


        }
        private static List<EntityObject> 获取块内部元素(Insert ins)
        {
            List<EntityObject> entities = new List<EntityObject>();
            Matrix3 transformation = ins.GetTransformation();
            Vector3 translation = ins.Position - transformation * ins.Block.Origin;

            foreach (EntityObject entity in ins.Block.Entities)
            {
                if (entity.Reactors.Count > 0)
                {
                    continue;
                }

                EntityObject newEntity = (EntityObject)entity.Clone();
                newEntity.TransformBy(transformation, translation);
                entities.Add(newEntity);
            }

            return entities;
        }

        private static DxfDocument Test(string file, string output = null)
        {
            // optionally you can save the information to a text file
            bool outputLog = !string.IsNullOrEmpty(output);
            TextWriter writer = null;
            if (outputLog)
            {
                writer = new StreamWriter(File.Create(output));
                Console.SetOut(writer);
            }

            // check if the dxf actually exists
            FileInfo fileInfo = new FileInfo(file);

            if (!fileInfo.Exists)
            {
                Console.WriteLine("THE FILE {0} DOES NOT EXIST", file);
                //Program.窗口.richTextBox1.AppendText(file + "不存在！" + "\n");

                Console.WriteLine();

                if (outputLog)
                {
                    writer.Flush();
                    writer.Close();
                }
                else
                {
                    Console.WriteLine("Press a key to continue...");
                    Console.ReadLine();
                }
                return null;
            }
            bool isBinary;
            DxfVersion dxfVersion = DxfDocument.CheckDxfFileVersion(file, out isBinary);

            // check if the file is a dxf
            if (dxfVersion == DxfVersion.Unknown)
            {
                Console.WriteLine("THE FILE {0} IS NOT A VALID DXF OR THE DXF DOES NOT INCLUDE VERSION INFORMATION IN THE HEADER SECTION", file);
                Console.WriteLine();

                if (outputLog)
                {
                    writer.Flush();
                    writer.Close();
                }
                else
                {
                    Console.WriteLine("Press a key to continue...");
                    Console.ReadLine();
                }
                return null;
            }

            // check if the dxf file version is supported
            if (dxfVersion < DxfVersion.AutoCad2000)
            {
                Console.WriteLine("THE FILE {0} IS NOT A SUPPORTED DXF", file);
                Console.WriteLine();

                Console.WriteLine("FILE VERSION: {0}", dxfVersion);
                Console.WriteLine();

                if (outputLog)
                {
                    writer.Flush();
                    writer.Close();
                }
                else
                {
                    Console.WriteLine("Press a key to continue...");
                    Console.ReadLine();
                }
                return null;
            }

            Stopwatch watch = new Stopwatch();
            watch.Start();
            DxfDocument dxf = DxfDocument.Load(file, new List<string> { @".\Support" });
            watch.Stop();

            // check if there has been any problems loading the file,
            // ins might be the case of a corrupt file or a problem in the library
            if (dxf == null)
            {
                Console.WriteLine("ERROR LOADING {0}", file);
                Console.WriteLine();

                Console.WriteLine("Press a key to continue...");
                Console.ReadLine();

                if (outputLog)
                {
                    writer.Flush();
                    writer.Close();
                }
                else
                {
                    Console.WriteLine("Press a key to continue...");
                    Console.ReadLine();
                }
                return null;
            }

            return dxf;
        }
        private static void Test2(DxfDocument dxf)
        {

            //bool kk=dxf.DrawingVariables.TryGetCustomVariable("$DIMTXTDIRECTION", out HeaderVariable variable);
            //    Console.WriteLine("\tCustomNames:{0}; ", kk);
            bool kk = dxf.DrawingVariables.RemoveCustomVariable("$DIMSTYLE");
            Console.WriteLine("\tRemoveCustomVariable:{0}; ", kk);

            //dxf.DrawingVariables.ClearCustomVariables();

            foreach (var o in dxf.DrawingVariables.KnownNames())
            {
                Console.WriteLine("\t KnownNames:{0}; ", o);

            }
            foreach (var o in dxf.DrawingVariables.KnownValues())
            {
                Console.WriteLine("\t KnownValues:{0}; ", o);

            }
            Console.WriteLine("\tCustomNames:{0}; ", "yyyyyyyyyyyyyyyyyyyyyyyy");
            foreach (var o in dxf.DrawingVariables.CustomNames())
            {
                Console.WriteLine("\tCustomNames:{0}; ", o);

            }
            //dxf.Save(@"D:\桌面\AAA.dxf");

            //Console.WriteLine("DIMENSION STYLES: {0}", dxf.DimensionStyles.Count);
            //foreach (var o in dxf.DimensionStyles)
            //{
            //    Console.WriteLine("\t{0}; References count: {1}", o.Name, dxf.DimensionStyles.GetReferences(o.Name).Count);
            //    Debug.Assert(ReferenceEquals(o.TextStyle, dxf.TextStyles[o.TextStyle.Name]), "Object reference not equal.");
            //    Debug.Assert(ReferenceEquals(o.DimLineLinetype, dxf.Linetypes[o.DimLineLinetype.Name]), "Object reference not equal.");
            //    Debug.Assert(ReferenceEquals(o.ExtLine1Linetype, dxf.Linetypes[o.ExtLine1Linetype.Name]), "Object reference not equal.");
            //    Debug.Assert(ReferenceEquals(o.ExtLine2Linetype, dxf.Linetypes[o.ExtLine2Linetype.Name]), "Object reference not equal.");
            //    if (o.DimArrow1 != null) Debug.Assert(ReferenceEquals(o.DimArrow1, dxf.Blocks[o.DimArrow1.Name]), "Object reference not equal.");
            //    if (o.DimArrow2 != null) Debug.Assert(ReferenceEquals(o.DimArrow2, dxf.Blocks[o.DimArrow2.Name]), "Object reference not equal.");
            //    Console.WriteLine("\t{0}; o.TextStyle: {1}", o.Name, o.TextDirection);
            //}
        }

        private static string 提取数字(string str)
        {
            string 返回值 = "";
            string strPatten = @"-sd([-\d.]+)";
            Regex rex = new Regex(strPatten, RegexOptions.IgnoreCase);
            MatchCollection matches = rex.Matches(str);

            //提取匹配项
            //foreach (Match match in matches)
            //{
            //    GroupCollection groups = match.Groups;
            //    Console.WriteLine("\t {0} 共有 {1} 个分组：{2}", match.Value, groups.Count, strPatten);

            //    //提取匹配项内的分组信息
            //    for (int i = 0; i < groups.Count; i++)
            //    {
            //        Console.WriteLine(
            //            string.Format("分组 {0} 为 {1}，位置为 {2}，长度为 {3}<br/>"
            //                        , i
            //                        , groups[i].Value
            //                        , groups[i].Index
            //                        , groups[i].Length));
            //    }
            //}
            if (matches.Count > 0)
            {

                返回值 = matches[0].Groups[1].Value;
                //Console.WriteLine("\t 返回值:{0}", 返回值);

                if (返回值 == "-1")
                {
                    返回值 = 板厚;
                }
                //return result[^1].Value;
            }
            else
            {
                //返回值 = "0.01";
                返回值 = "0";
            }
            return 返回值;
            //MatchCollection result = Regex.Matches(str, @"(sd)([\d]+)");
            ////Regex.RegexOptions.IgnoreCase;
            //for (int i = 0; i < result.Count; i++)
            //{
            //    Console.WriteLine("\t 匹配对象:{0}", result[i]);
            //}
            ////Regex rgx = new Regex(@"sd([\d]+)", RegexOptions.IgnoreCase);
            //////string sentence = "Who writes these notes and uses our paper?";
            ////Match match = rgx.Match(拟匹配字符串);
            ////return match.Success;
            ////Console.WriteLine("\t result:{0}", result);

            //if (result.Count > 0)
            //{
            //    Console.WriteLine("\t 匹配对象:{0}", result[^1]);//获取倒数第一个元素
            //    return result[^1].Value;
            //}
            //else
            //{
            //    return "0";
            //}

        }
        public static void ToPolyline2D()
        {
            DxfDocument dxf = new DxfDocument();

            Vector3 center = new Vector3(1, 8, -7);
            Vector3 normal = new Vector3(1, 1, 1);

            Circle circle = new Circle(center, 7.5);
            circle.Normal = normal;

            Arc arc = new Arc(center, 5, -45, 45);
            arc.Normal = normal;

            Ellipse ellipse = new Ellipse(center, 15, 7.5);
            ellipse.Rotation = 35;
            ellipse.Normal = normal;

            Ellipse ellipseArc = new Ellipse(center, 10, 5);
            ellipseArc.StartAngle = 315;
            ellipseArc.EndAngle = 45;
            ellipseArc.Rotation = 35;
            ellipseArc.Normal = normal;

            dxf.Entities.Add(circle);
            dxf.Entities.Add(circle.ToPolyline2D(1000));

            //dxf.Entities.Add(arc);
            //dxf.Entities.Add(arc.ToPolyline2D(10));

            //dxf.Entities.Add(ellipse);
            //dxf.Entities.Add(ellipse.ToPolyline2D(10));

            //dxf.Entities.Add(ellipseArc);
            //dxf.Entities.Add(ellipseArc.ToPolyline2D(10));

            dxf.Save("to polyline.dxf");

            dxf = DxfDocument.Load("to polyline.dxf");

            dxf.Save("to polyline2.dxf");
        }

    }
}
